#ifndef CUSTOM_CONTROLS_HPP
#define CUSTOM_CONTROLS_HPP

#include "sql/types.hpp"
#include <functional>

#include "imgui/imgui.h"
#include "imgui/IconsFontAwesome4.h"

extern const char* default_ok_cancel_button_text[];

namespace ImGui
{
    // 第几个按钮点击了
    using ButtonCallback = std::function<void(int, void*)>;

    /**
     * 在窗口的底部绘制一排按钮
     */
    void WindowBottomButtons(
        int button_count,
        const char* button_texts[],
        ButtonCallback callback,
        void* user_data);

    /**
     * 绘制标签，并提供几个按钮
     */
    bool RenderTag(
        const Tag& tag,
        const char* button_texts[],
        const ButtonCallback& callback,
        void* user_data);

    /**
     * 获取标签渲染时需要的宽度
     */
    float GetTagRenderWidth(
        const Tag& tag,
        const char* button_texts[]);

    /**
     * 一种环形进度显示控件
     */
    void Spinner(float radius, float thickness, int num_segments, const ImVec4& color);

    /**
     * 当在某个Item上放置鼠标指针达到一定时长时生成一个自定义Tooltip
     * @param drawCalls tooltips的内容
     * @param delta_time 需要放置多长时间，单位秒
     */
    void LongHoveredTooltips(const std::function<void()>& drawCalls, double delta_time = 0.5);

    /**
     * 时间编辑器，使用小时:分钟来编辑时间，结果转换为浮点数，单位为小时
     * @param time_store 存储时间（单位小时）的浮点数变量指针
     */
    void AlternativeTimeEditor(double *time_store);

    /**
     * 绘制一个带有颜色的圆
     * @param center_pos 圆心坐标
     * @param radius 半径
     * @param colors 使用的颜色列表
     * @param color_cnt 颜色数量
     */
    void DrawColoredCircle(ImVec2 center_pos, float radius, const ImU32* colors, int color_cnt);

    void BeginGroupPanel(const char* name, const ImVec2& size = ImVec2(0.0f, 0.0f));

    void EndGroupPanel();

    void CenteredText(const char *fmt, ...);

    /**
     * @brief 整数编辑控件，label： - [editor] + 样式
     * 
     * @param label 显示标签 
     * @param value 数值
     * @param fmt 显示格式
     * @param step 步进
     * @return 是否发生更改
     */
    bool NumericUpDown(const char *label, int *value, const char *fmt = nullptr, int step = 1);


    enum class LoopState {
        eNormal, // 正常编辑
        eOverflow, // 已经触发上溢出
        eUnderflow, // 已经触发下溢出
    };

    /**
     * @brief 与NumericUpDown类似，但是限制了数据范围在[min,max]
     * 
     * @param label 显示标签
     * @param value 数值
     * @param min 最小值
     * @param max 最大值
     * @param state 循环状态
     * @param fmt 显示格式
     * @param step 步进
     * @return 是否发生更改
     */
    bool NumericUpDownLoop(const char *label, int *value, int min, int max, LoopState *state = nullptr, const char *fmt = nullptr, int step = 1);

    /**
     * @brief 选择优先级
     * 
     * @param label 标签，提示文本
     * @param priority 当前优先级
     * @return true 优先级更改了
     * @return false 优先级未更改
     */
    bool SelectPriority(const char *label, int *priority);
}

#endif // CUSTOM_CONTROLS_HPP
